home *** CD-ROM | disk | FTP | other *** search
- unit Lists;
-
- {--------------------------------------------------------------------------}
- { Abstract Data Type for dynamically sized list }
- { By Michael Dales 30th May 1996 }
- { }
- { Here is a simple list unit, that has the advantage of being dynamically }
- { sized, unlike normal arrays. To use the list you only need to know the }
- { data type names and the methods declared in the interface of this unit }
- { are used to manipulate them without the need to know the underlying }
- { representation. }
- { }
- { Deaclare your list variable to be of type TList, and remeber to use }
- { CreateList on it before you carry out any operations using it. Data is }
- { stored in nodes as pointers, just so you can have a list which isn't }
- { tied to just one kind of data type. Remeber though that because of this }
- { you'll need to typecast your pointers when you retrieve them from the }
- { list. Each node is has a type called PListNode, and an invalid node has }
- { the value null. }
- { }
- { Email comments to: 9402198d@udcf.gla.ac.uk }
- { URL: http://www.gla.ac.uk/Clubs/WebSoc/~9402198d/index.html }
- {--------------------------------------------------------------------------}
-
- interface
-
- const null = nil; {Non specific terminator}
-
- type PListNode = ^TListNode; {Pointer to node}
- TListNode = record {Node record}
- Item : Pointer; {Pointer to node data}
- Next : PListNode; {Next node}
- Previous : PListNode; {Previous node}
- end;
-
- TList = record {Holder for list}
- First : PListNode; {Pointer to start of list}
- Rear : PListNode; {Pointer to end of list}
- Size : integer; {Size of list}
- end;
-
- {CreateList - Initiates a new list}
- procedure CreateList(var L : TList);
-
- {DestroyList - Frees up all memory used by list and sets list to nil}
- procedure DestroyList(var L : TList);
-
- {AddNewNode - Adds new node to list L, filling it with the data
- supplied. Returns true is new node sucessfully
- added, otherwise returns false.}
- procedure AddNewNode(var L : TList; Data : Pointer);
-
- {DeleteListElement - Deletes an element passed.}
- procedure DeleteNode(var L : TList; ANode : PListNode);
-
- {GetFirstNode - Returns the first node in a given list}
- function GetFirstNode(L:TList):PListNode;
-
- {GetNextNode - Returns the successor of the given node}
- function GetNextNode(Node:PListNode):PListNode;
-
- {GetNodeData - Returns the data in a specific node}
- procedure GetNodeData(Node:PListNode; var Data:Pointer);
-
- {UpdateNode - Replaces a nodes details with new ones}
- procedure UpdateNode(Node:PListNode; Data:Pointer);
-
- {--------------------------------------------------------------------------}
- implementation
- {--------------------------------------------------------------------------}
-
- {CreateList - Initiates a new list}
-
- procedure CreateList(var L : TList);
- begin
- L.First := nil; {No list yet}
- L.Rear := nil;
- L.Size := 0; {No length yet}
- end;
-
-
- {RemoveLastNode - Deletes last node on the list}
-
- procedure RemoveLastNode(var L : TList);
- begin
- with L do {With the list}
- begin
- if Size > 0 then {If nodes in list}
- begin
- if Size = 1 then {If just one node}
- begin
- if First^.Item <> nil then {If data in node then}
- Dispose(First^.Item); {Dispose of it}
- Dispose(First); {Dispose of first node}
- First := nil;
- Rear := nil; {Set rear to nil}
- end else
- begin {If more than one node}
- Rear := Rear^.Previous; {Set rear to second last}
- Dispose(Rear^.Next); {Remove last node}
- end;
- Size := Size-1; {Decrement list size}
- end;
- end;
- end;
-
-
- {DestroyList - Frees up all memory used by list and sets list to nil}
-
- procedure DestroyList(var L : TList);
- begin
- while L.First <> nil do {While still nodes left}
- RemoveLastNode(L); {Remove last node}
- CreateList(L);
- end;
-
-
- {GetFirstNode - Returns the first node in a given list}
-
- function GetFirstNode(L : TList) : PListNode;
- begin
- GetFirstNode := L.First;
- end;
-
-
- {GetNextNode - Returns the successor of the given node}
-
- function GetNextNode(Node : PListNode) : PListNode;
- begin
- if Node <> nil then
- GetNextNode := Node^.Next
- else
- GetNextNode := nil;
- end;
-
-
- {GetNodeData - Returns the data in a specific node}
-
- procedure GetNodeData(Node : PListNode; var Data : Pointer);
- begin
- if Node <> nil then
- Data := Node^.Item
- else
- Data := nil;
- end;
-
-
- {AddNewNode - Adds new node to list L, filling it with the data
- supplied. Returns true is new node sucessfully
- added, otherwise returns false.}
-
- procedure AddNewNode(var L:TList; Data:Pointer);
- var temp : PListNode;
- begin
- new(temp); {Create new node}
- with temp^ do {Fill node}
- begin
- Item := Data;
- Next := nil;
- Previous := L.Rear;
- end;
- If (L.Size = 0) then {If empty list...}
- begin
- L.First := temp; {Add as first node}
- L.Rear := temp;
- end else {else add at end}
- begin
- L.Rear^.Next := temp; {Make old rear of list point to new}
- L.Rear := temp; {Make rear point to new node}
- end;
- L.Size := L.Size + 1; {Increment list length}
- end;
-
-
- {UpdateNode - Replaces a nodes details with new ones}
-
- procedure UpdateNode(Node : PListNode; Data : Pointer);
- begin
- if Node <> nil then
- begin
- Node^.Item := Data;
- end;
- end;
-
-
- {DeleteListElement - Deletes an element passed.}
-
- procedure DeleteNode(var L : TList; ANode : PListNode);
- begin
- if (L.Size = 1) or (ANode^.Next = nil) then {If we're deeling with}
- RemoveLastNode(L) {last node then that's easy}
- else {otherwise...}
- begin
- if (ANode = L.First) then {if we're deleting the first node}
- begin
- L.First := L.First^.Next; {Start list from second node}
- L.First^.Previous := nil; {Set new starts previous link}
- Dispose(ANode); {Dispose of old first}
- end else
- begin
- ANode^.Previous^.Next := ANode^.next; {Move pointers...}
- ANode^.Next^.Previous := ANode^.Previous;
- Dispose(ANode); {Dispose of node}
- end;
- L.Size := L.Size-1; {Note new list size}
- end;
- end;
-
- end.